package com.vcredit.creditcat.service.speedloan.xrf;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.vcredit.creditcat.dto.speedloan.CheckCustResultDto;
import com.vcredit.creditcat.exception.BirdRequestException;
import com.vcredit.creditcat.exception.ProductCanNotApplyException;
import com.vcredit.creditcat.model.AuthIdentity;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustAccount;
import com.vcredit.creditcat.model.ProductCheckcustItem;
import com.vcredit.creditcat.service.AuthIdentityService;
import com.vcredit.creditcat.service.CustAccountService;
import com.vcredit.creditcat.service.speedloan.CommonProductCheckCustService;
import com.vcredit.creditcat.service.speedloan.ProductCheckCustServiceAdaptor;
import com.vcredit.creditcat.util.RSAUtil;
import com.vcredit.framework.util.HttpRequest;
import com.vcredit.framework.util.JacksonUtil;

@Service(ProductCheckCustServiceAdaptor.BEANNAME_PREFIX + 25)
public class XRFCheckCustService extends CommonProductCheckCustService {
	private static Logger logger = LoggerFactory.getLogger(XRFCheckCustService.class);
	@Autowired
	private CustAccountService custAccountService;
	@Autowired
	private AuthIdentityService authIdentityService;
	/** 对接用的url **/
	@Value("${crf.applay.url}")
	private String creditCrftestUrl;

	@Value("${crf.xinyongmao.dataSource}")
	private String dataSource;

	@Value("${crf.xinyongmao.key}")
	private String key;

	@Value("${crf.promotion.url}")
	private String promotionUrl;

	@Value("${crf.promotion.code}")
	private String promotionCode;

	@Value("${crf.promotion.key}")
	private String promotionKey;

	@Override
	protected CheckCustResultDto handlerCheckItem(ProductCheckcustItem checkItem, int itemType, Cust cust, Long productId) {
		// TODO Auto-generated method stub
		try {
			int itemId = Integer.parseInt(checkItem.getCheckItemId() + "");
			if (itemType == 0) { // 原始认证项
				switch (itemId) {
				case 1:
					Object productCheckCreditParam = this.getProductCheckCreditParam(cust);
					Object checkCreditResult = this.checkCredit(productCheckCreditParam);
					Object dealResult = this.checkCreditResult(checkCreditResult);
					// 撞库返回
					if (null == dealResult) {
						return CheckCustResultDto.fail("已经注册！");
					}
					break;
				default:
					break;
				}
			}
		} catch (ProductCanNotApplyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return CheckCustResultDto.success();
	}

	/**
	 * 封装撞库信息
	 * 
	 * @param cust
	 * @return
	 */
	public Object getProductCheckCreditParam(Cust cust) {
		Long lastProccessId = cust.getLastProccessId();
		AuthIdentity identity = authIdentityService.findByProcessId(lastProccessId);
		CustAccount account = new CustAccount();
		account.setCustId(cust.getCustId());
		List<CustAccount> accountList = custAccountService.find(account);
		Map<String, String> map = new HashMap<>();
		map.put("phone", accountList.get(0).getUserName());// 手机号
		map.put("name", identity.getName());// 姓名
		map.put("idNum", identity.getCitizenId());// 身份证号
		return map;
	}

	@SuppressWarnings("rawtypes")
	public Object checkCredit(Object parmDto) throws ProductCanNotApplyException, Exception {
		String resultJson = "";
		Map<String, String> map = (Map<String, String>) parmDto;
		try {
			String queryPar = toQueryString(map, true);
			byte[] data = queryPar.getBytes();
			byte[] encodedData = RSAUtil.encryptByPublicKey(data, promotionKey);
			String dataCrypted = new String(Base64.encodeBase64(encodedData));
			String sign = URLEncoder.encode(dataCrypted, StandardCharsets.UTF_8.name());
			map.put("systemCode", promotionCode);
			map.put("sign", sign);
			StringBuilder sb = new StringBuilder();
			sb = sb.append(promotionUrl).append("?");
			for (Map.Entry<String, String> entry : map.entrySet()) {
				sb = sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
			}
			String url = sb.toString();
			String urlReal = url.substring(0, url.length() - 1);
			resultJson = HttpRequest.doGet(urlReal);
			Map result = JacksonUtil.Json2Map(resultJson);
			return result;
		} catch (Exception e) {
			if (e instanceof ProductCanNotApplyException) {
				throw new ProductCanNotApplyException(e.getMessage());
			} else {
				logger.info(e.toString());
				throw new BirdRequestException("网络开小差, 请重新尝试哦。");
			}
		}
	}

	/**
	 * 把一个map拼接成一个get请求查询传
	 * 
	 * @param map
	 *            map里面只应有业务查询参数,不应该包含sign和code
	 * @param needEncode
	 *            是否使用URLEncode编码,默认为ture
	 **/
	private String toQueryString(Map<?, ?> data, boolean needEncode) throws UnsupportedEncodingException {
		String[] keys = data.keySet().toArray(new String[data.size()]);
		Arrays.sort(keys);
		StringBuffer queryString = new StringBuffer();
		for (String key : keys) {
			queryString.append(key + "=");
			if (needEncode) {
				queryString.append(URLEncoder.encode((String) data.get(key), StandardCharsets.UTF_8.name()) + "&");
			} else {
				queryString.append(data.get(key) + "&");
			}
		}
		if (queryString.length() > 0) {
			queryString.deleteCharAt(queryString.length() - 1);
		}
		return queryString.toString();
	}

	public Object checkCreditResult(Object commitOutput) throws Exception {
		if (commitOutput != null) {
			Map map = (Map) commitOutput;
			if ("1".equals(map.get("code"))) {
				return map;
			}
		}
		return null;
	}
}
